home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
FROMUTS
/
UNIXLIB37B
/
src
/
c
/
alloc_
< prev
next >
Wrap
Text File
|
1992-12-30
|
8KB
|
460 lines
#ifdef __STDC__
static char sccs_id[] = "@(#) alloc.c 4.0 "__DATE__" HJR";
#else
static char sccs_id[] = "@(#) alloc.c 4.0 15/9/90 HJR";
#endif
/* alloc.c (c) Copyright 1990 H.Rogers */
/* features multiple free lists hashed on block size */
#ifdef __STDC__
#include <stddef.h>
#include <stdlib.h>
extern void *sbrk(int);
#else
#include "sys/types.h"
void *malloc();
void *realloc();
void free();
extern void *sbrk();
#endif
#include <string.h>
#ifdef M_DEBUG
#include <stdio.h>
#include <signal.h>
#ifdef __STDC__
static int __m_fail(char *exp,char *file,int line)
#else
extern int kill();
extern int getpid();
#define raise(x) kill(getpid(),x)
static int __m_fail(exp,file,line)
char *exp,*file;
int line;
#ifndef SIGABRT
#define SIGABRT SIGQUIT
#endif
#endif
{
fprintf(stderr,"\n\"%s\", line %d: Assertion failed: %s\n",file,line,exp);
raise(SIGABRT);
return(0);
}
#ifdef __STDC__
#define assert(x) (void)((x) ? 0 : __m_fail(#x,__FILE__,__LINE__))
#else
#ifndef __FILE__
#define __FILE__ "alloc.c"
#endif
#ifndef __LINE__
#define __LINE__ 0
#endif
#define assert(x) (void)((x) ? 0 : __m_fail("x",__FILE__,__LINE__))
#endif
#ifdef ARCH
#include "sys/syslib.h"
#define addr(x) ((void *)(x) >= __base && (void *)(x) < __break)
#else
#define addr(x) ((x) ? ((*x) | 1) : 0) /* force SIGSEGV if bad */
#endif
#define MAGIC 0x4349474d
#endif
typedef struct _blk
{
#ifdef M_DEBUG
int magic;
struct _blk *range;
#endif
struct _blk *next;
size_t size;
} blk;
#ifdef M_DEBUG
#define BLKSIZ 16 /* smallest power of 2 >= sizeof(blk) */
#else
#define BLKSIZ 8
#endif
#define blkalign(x) (((x) + (BLKSIZ<<1) - 1) & (~(BLKSIZ - 1)))
#define NFL 8
static blk __fl[NFL];
static size_t __flmin[NFL] =
{
4096 + BLKSIZ,
1024 + BLKSIZ,
256 + BLKSIZ,
64 + BLKSIZ,
32 + BLKSIZ,
16 + BLKSIZ,
8 + BLKSIZ,
0 + BLKSIZ /* catchall */
};
#define MEMINC 4096 /* sbrk() memory increment */
#ifdef __STDC__
void __allocinit(void)
#else
void __allocinit()
#endif
{
register blk *b;
register int i;
#ifdef M_DEBUG
assert(sizeof(struct _blk) >= BLKSIZ);
#endif
for (i = 0; i < NFL; i++)
{
b = __fl + i;
b->next = b;
b->size = BLKSIZ;
#ifdef M_DEBUG
b->magic = MAGIC;
b->range = __fl + ((i + 1) % NFL);
#endif
}
}
#ifdef __STDC__
void *malloc(register size_t size)
#else
void *malloc(size)
register size_t size;
#endif
{
register blk *b,*p,*q;
register int i;
if (!(size = blkalign(size))) return(0);
for (i = 0; size < __flmin[i]; i++);
q = 0;
p = __fl + i;
b = p->next;
#ifdef M_DEBUG
assert(addr(p));
assert(p->magic == MAGIC);
assert(addr(p->range));
assert(p->range->magic == MAGIC);
#endif
while (b > p)
{
#ifdef M_DEBUG
assert(addr(b));
assert(addr(b->next));
assert(b->magic == MAGIC);
assert(addr(b->range));
assert(b->range->magic == MAGIC);
#endif
if (b->size >= size)
{ p->next = b->next; goto malloc; }
q = p;
p = b;
b = b->next;
}
{
register void *m;
register int _size;
#ifdef M_DEBUG
register blk *r;
#endif
_size = (size/MEMINC + 1) * MEMINC;
if ((m = sbrk(_size)) == (void *)-1) return(0);
if ((char *)p + p->size == (char *)m)
{
#ifdef M_DEBUG
assert(q);
#endif
b = p; p = q; p->next = b->next;
b->size += _size;
}
else
{
b = (blk *)m;
b->size = _size;
#ifdef M_DEBUG
b->magic = MAGIC;
for (r = p; r->range > r; r = r->range);
assert(addr(r));
assert(addr(r->range));
b->range = r->range;
r->range = b;
#endif
}
#ifdef M_DEBUG
assert(addr(b));
#endif
}
malloc:
if (b->size > (size + __flmin[i]))
{
register blk *n;
register int j;
j = b->size - size;
n = (blk *)((char *)b + size);
n->next = p->next;
p->next = n;
n->size = j;
b->size = size;
#ifdef M_DEBUG
n->magic = MAGIC;
n->range = b->range;
b->range = n;
#endif
}
#ifdef M_DEBUG
assert(b->magic == MAGIC);
assert(b->range->magic == MAGIC);
#endif
return((void *)((char *)b + BLKSIZ));
}
#ifdef __STDC__
void *realloc(register void *_a,register size_t size)
#else
void *realloc(_a,size)
register void *_a;
register size_t size;
#endif
{
register blk *a,*b,*p,*q;
register int i;
int j;
if (!(_a)) return(malloc(size));
if (!(size = blkalign(size))) { free(_a); return(0); }
#ifdef M_DEBUG
assert(addr(_a));
#endif
a = (blk *)((char *)_a - BLKSIZ);
#ifdef M_DEBUG
assert(addr(a));
assert(a->magic == MAGIC);
assert(addr(a->range));
assert(a->range->magic == MAGIC);
#endif
for (i = 0; a->size < __flmin[i]; i++);
q = 0;
p = __fl + i;
b = p->next;
#ifdef M_DEBUG
assert(addr(p));
assert(p->magic == MAGIC);
assert(addr(p->range));
assert(p->range->magic == MAGIC);
#endif
while (b > p)
{
#ifdef M_DEBUG
assert(addr(b));
assert(addr(b->next));
assert(b->magic == MAGIC);
assert(addr(b->range));
assert(b->range->magic == MAGIC);
#endif
if (b > a) break;
q = p;
p = b;
b = b->next;
}
while ((char *)a + a->size == (char *)b)
{
a->size += b->size;
#ifdef M_DEBUG
assert(a->range == b);
a->range = b->range;
b->magic = 0;
#endif
b = p->next = b->next;
}
j = a->size - BLKSIZ;
if (a->size < size)
{
if ((char *)p + p->size == (char *)a && p->size + a->size >= size)
{
#ifdef M_DEBUG
assert(q);
#endif
b = p; p = q;
b->size += a->size;
#ifdef M_DEBUG
assert(b->range == a);
b->range = a->range;
a->magic = 0;
#endif
memmove((char *)b + BLKSIZ,_a,j); _a = (char *)(a = b) + BLKSIZ;
b = p->next = b->next;
}
else
{
register void *__a;
if (!(__a = malloc(size - BLKSIZ))) return(0);
memcpy(__a,_a,j);
free(_a);
return(__a);
}
}
if (a->size > (size + __flmin[i]))
{
register blk *n;
register int j;
j = a->size - size;
n = (blk *)((char *)a + size);
n->next = p->next;
p->next = n;
n->size = j;
a->size = size;
#ifdef M_DEBUG
n->magic = MAGIC;
n->range = a->range;
a->range = n;
#endif
}
#ifdef M_DEBUG
assert(a == (blk *)((char *)_a - BLKSIZ));
assert(a->magic == MAGIC);
assert(addr(a->range));
assert(a->range->magic == MAGIC);
#endif
return(_a);
}
#ifdef __STDC__
void free(register void *_a)
#else
void free(_a)
register void *_a;
#endif
{
register blk *a,*p,*b;
register int i;
if (!_a) return;
#ifdef M_DEBUG
assert(addr(_a));
#endif
a = (blk *)((char *)_a - BLKSIZ);
#ifdef M_DEBUG
assert(addr(a));
assert(a->magic == MAGIC);
assert(addr(a->range));
assert(a->range->magic == MAGIC);
#endif
for (i = 0; a->size < __flmin[i]; i++);
p = __fl + i;
b = p->next;
#ifdef M_DEBUG
assert(addr(p));
assert(p->magic == MAGIC);
assert(addr(p->range));
assert(p->range->magic == MAGIC);
#endif
while (b > p)
{
#ifdef M_DEBUG
assert(addr(b));
assert(addr(b->next));
assert(b->magic == MAGIC);
assert(addr(b->range));
assert(b->range->magic == MAGIC);
#endif
if (b > a) break;
p = b;
b = b->next;
}
while ((char *)a + a->size == (char *)b)
{
a->size += b->size;
#ifdef M_DEBUG
assert(a->range == b);
a->range = b->range;
b->magic = 0;
#endif
b = p->next = b->next;
}
if ((char *)p + p->size == (char *)a)
{
p->size += a->size;
#ifdef M_DEBUG
assert(p->range == a);
p->range = a->range;
a->magic = 0;
#endif
}
else
{
a->next = p->next;
p->next = a;
}
}
#ifdef M_DEBUG
#ifdef __STDC__
void __m_debug(void) /* dump free lists */
#else
void __m_debug()
#endif
{
register blk *b;
register int i;
for (i = 0; i < NFL; i++)
{
printf("\nfl: %d ( >= %d )\n",i,__flmin[i] - BLKSIZ);
b = __fl + i; do
{
b = b->next;
printf("%7x: next: %7x [%7x] size: %x\n",b,b->next,
(char *)b + b->size,b->size - BLKSIZ);
assert(addr(b));
assert(b->magic == MAGIC);
}
while (b->next > b);
}
putchar('\n');
}
#endif